<template>
  <div v-if="source.data.id && source.data.cellData" class="OctopusList">
    <!--    {{source.data}}-->
    <div class="Operation" v-if="created || exported">
      <el-button type="success" v-if="created" v-on:click="created">Create</el-button>
      <el-button type="warning" v-if="exported" v-on:click="output">Export</el-button>
      <el-button type="info" v-if="backed" v-on:click="backed">Back</el-button>
      <el-button v-for="(button,buttonKey) in source.button" :key="buttonKey"
                 v-bind="{type: button.class}" v-on:click="event(button.click)">
        {{button.text}}
      </el-button>
      <!--  output(source.data.cellData)-->
      <!--      <div class="btn info Button" v-on:click="open()">New Window</div>-->
    </div>
    <div class="Search" v-if="!source.data.parentModel && isSearch">
      <!-- 如果范围的则宽度翻倍，如果宽度大于200则呈现200 -->
      <div v-bind:class="'Item'" v-for="(cell,cellIndex) in source.data.cellData"
           :key="cellIndex"
           v-bind:style="{width:(cell.searchKey.toLocaleUpperCase() == 'BETWEEN'?cell.width*2:cell.width > 150? 150:cell.width+50)+'px'}"
           v-if="!octopus.tools.IsNullOrEmpty(cell.searchKey) && cell.show">
        <div class="DisplayName">
          {{cell.displayName}}：
        </div>
        <!--针对BETWEEN范围查询，统一渲染2个控件，适用于数字、整型、日期，除此之外全部是单值绑定，如果控件自己有多选，则控件返回数组集合。-->
        <template v-if="cell.searchKey.toLocaleUpperCase() == 'BETWEEN'">
          <div v-bind:style="{width:(cell.width)+'px',float:'left'}">
            <o-control v-bind="{data:cell,index:0}" v-bind:changed="change"
                       v-model.lazy="cell.searchValue[0]"></o-control>
          </div>
          <div v-bind:style="{width:(cell.width)+'px',float:'left','padding-left':'5px'}">
            <o-control v-bind="{data:cell,index:1}" v-bind:changed="change"
                       v-model.lazy="cell.searchValue[1]"></o-control>
          </div>
        </template>
        <template v-else>
          <o-control v-bind="{data:cell}" v-bind:changed="change"
                     v-model.lazy="cell.searchValue"></o-control>
        </template>
      </div>
    </div>
    <div class="Data"
         v-bind:style="{width:source.data.width == 'auto' || source.data.width == undefined ?'100%':source.data.width}">
      <div class="Head" ref="LIST_HEAD">
        <div class="Panel" v-bind:style="{width:(source.reallyWidth + 1000) + 'px'}">
          <div v-if="source.showNumber" v-bind:style="{width:source.numberWidth + 'px'}">&nbsp;</div>
          <div class="Config" v-if="viewed || modified || deleted || source.configWidth"
               v-bind:style="{width:source.configWidth + 'px'}">&nbsp;
          </div>
          <div class="Column" v-for="(cell,cellIndex) in source.data.cellData" :key="cellIndex" v-if="cell.show"
               v-bind:style="{width:cell.width + 'px'}" v-on:click="sort(cell)">
            {{ cell.displayName }}
          </div>
          <div class="End" style="width: 1000px;">&nbsp;</div>
        </div>
      </div>
      <div class="Content" v-on:scroll="scroll($event.target)" v-bind:style="{height:control_height}">
        <div class="Panel" v-bind:style="{width:source.reallyWidth + 'px'}"
             :key="rowIndex"
             v-for="(row,rowIndex) in source.data.queryData">
          <div class="Number" v-if="source.showNumber"
               v-bind:style="{width:source.numberWidth + 'px',height:row_height+'px'}">{{parseRowNumber(rowIndex)}}
          </div>
          <div class="Config" v-if="viewed || modified || deleted || source.configWidth"
               v-bind:style="{width:source.configWidth + 'px',height:row_height+'px'}">

            <slot name="config" :data="{row:row,cell:source.data.cellData}"></slot>

            <span class="View icon icongongdanxitong-" v-if="viewed"
                  v-on:click="viewed(row)"></span>
            <span class="Modify icon iconbianjisekuai" v-if="modified"
                  v-on:click="modified(row)"></span>
            <span class="Delete icon iconguanbi" v-if="deleted"
                  v-on:click="del(row)"></span>
          </div>
          <div v-for="(cell,cellDataIndex) in source.data.cellData" v-if="cell.show"
               :title="cell.controlTypeID!='15' ? row[cell.name]:''"
               :key="cellDataIndex" v-bind:style="{width:cell.width + 'px',height:row_height+'px'}">
            <div v-if="cell.controlTypeID==15 && row[cell.name]!= ''" class="ColumnBody">
              <img v-for="image in JSON.parse(row[cell.name])" :src="image.url" :title="image.name"
                   v-on:click="renderImageView(image.url)"/>
            </div>
            <div v-else class="ColumnBody" v-html="parseCellValue(row,cell.name)">
            </div>
            <!--{{row[cell.name] == null?'&nbsp;':(row[cell.name].toString().length>0?row[cell.name]:'&nbsp;') }}-->
          </div>
          <!--<tr v-for="row in source.data.queryData">-->
          <!--<td v-for="(value,key,index)  in row" style="border: 1px solid #176b94; ">-->
          <!--{{ key }}: {{ value }}: {{ index }}-->
          <!--</td>-->
          <!--</tr>-->
        </div>
      </div>
    </div>
    <!--&& !source.data.parentModel-->
    <div class="Page" v-if="!octopus.tools.IsNullOrEmpty(source.data.pageData)">
      <table>
        <tr>
          <td class="TotalInfo">
            <span>现<b>{{source.data.pageData.totalRows}}</b>条数据</span>
          </td>
          <td class="TotalInfo">
            <span>共<b>{{source.data.pageData.totalPages}}</b>页</span>
          </td>
          <td v-bind:class="page.type" :key="pageIndex" v-for="(page,pageIndex) in source.data.pageData.listData"
              v-on:click="jump(page.index)">
            <span v-bind:class="page.class">{{page.text}}</span>
            <!--{{renderPage(page)}}-->
          </td>
        </tr>
      </table>
    </div>
    <!-- 图像预览控件，要移动到body下才行，否则会和Bootstrap冲突。 -->
    <el-dialog :visible.sync="imageViewPanel">
      <img width="100%" :src="imageViewPath" alt="">
    </el-dialog>
    <div note="测试用" style="border: 1px solid #b6b6b6;width:100%;margin-top:10px;padding: 3px;display: none">
      <div v-on:click="subFun('112233')">父级组件事件测试（调用父组件方法，子传父）</div>
      <div v-on:click="pushFatherFun">当前组件事件测试（子传父）</div>
    </div>
  </div>
  <div v-else>Octopus Framework Initialization Exception.</div>
</template>

<script>
  export default {
    name: 'ListEngine', /* 这个name暂时不知道用啥用，根据官方文档说的是方便排错的 */
    data() {
      return {
        octopus: this.$parent.octopus,
        control_height: "0px",
        row_height: 0,
        imageViewPanel: false, // 图像面板显示
        imageViewPath: '',     // 图像预览地址
        isSearch: true,// 开启搜索
      }
    },
    created: function () {
      // 初始化查询数据，对前端数据进行整理。
      this.init();
      // console.log("created: " + JSON.stringify(this.source.data.id));
      // 获取父级的父级的属性
      // this.$parent.$parent.octopus.tips.debug("Octopus List Engin Is Load.");
      this.octopus.tips.debug("[" + this.source.data.id + "] ListEngine执行了created事件。");

      // console.log("===============--------")
      // console.log(this.$slots); //获取绑定组件。
    },
    mounted: function () {
      this.octopus.tips.debug("[" + this.source.data.id + "] ListEngine执行了mounted事件。");
    },
    beforeUpdate: function () {
      this.octopus.tips.debug("[" + this.source.data.id + "] ListEngine执行了beforeUpdate事件。");
    },
    updated: function () {
      this.octopus.tips.debug("[" + this.source.data.id + "] ListEngine执行了updated事件。");
    },
    activated: function () {
      this.load();
      this.octopus.tips.debug("[" + this.source.data.id + "] ListEngine执行了activated事件。");
    },
    deactivated: function () {
      this.octopus.tips.debug("[" + this.source.data.id + "] ListEngine执行了deactivated事件。");
    },
    diyyy: function () {
      // this.octopus.tips.debug("List.vue执行了 diy function 事件。");
      console.log("执行了Diy方法，但是这个自定义DIY方法获取不到原型链上的数据。。。比如this.octopus.tips.debug()。");
    },
    computed: {
      // 如果cellData数据发生了改变,则触发这个事件。
      changeCell: function () {
      },
      changePage: function () {

      }
    },
    methods: {
      init: function () {
        this.initData();
        this.initSearch();
        this.initConfig();
      },
      initData: function () {
        // 保存整体控件，给后续引用方法，调用使用，极其方便。
        this.source.control = this;

      },
      // 初始化查询
      initSearch: function () {
        let o = this;
        let searchKeys = 0;
        $(this.source.data.cellData).each(function (index, item) {
          // 确保包含SearchKey
          if (item.searchKey) {
            // 转义成字符串，然后才能使用方法。。。
            let key = (item.searchKey + "").toLocaleUpperCase();
            // 如果是范围查询，扩展searchValue的数据值为2个。
            if (key == "BETWEEN") {
              item.searchValue = ["", ""];
            }
            searchKeys = searchKeys + 1;
          }
        });
        // 如果没有一个查询列，则不显示查询框。
        this.isSearch = searchKeys == 0 ? false : true;
      },
      initConfig: function () {
        if (!this.source.configWidth) {
          // 动态识别配置列宽度
          this.source.configWidth = 4;
          let baseWidth = 17;
          if (this.viewed) {
            this.source.configWidth += baseWidth;
          }
          if (this.modified) {
            this.source.configWidth += baseWidth;
          }
          if (this.deleted) {
            this.source.configWidth += baseWidth;
          }
        }
      },
      // 初始化link数据
      loadLinkData: function () {
        let o = this;
        // 八爪鱼托管赋值
        $(this.source.data.cellData).each(function (index, cell) {
          if (cell.link) {
            // 循环link数据，并自动配置绑定的name。
            $(cell.link).each(function (linkIndex, linkData) {
              // 循环当前列，进行匹配。
              $(o.source.data.cellData).each(function (index_root, cell_root) {
                if (linkData.binding == cell_root.name) {
                  // console.warn(linkData.binding + "," + cell_root.name + "," + JSON.stringify(cell_root));
                  linkData.name = cell_root.displayName;
                }
              });
            });
          }
        });
      },
      // 控件变化触发，同时触发search回调事件。
      change: function (new_cell, old_cell) {
        let o = this;
        // 处理关联数据
        setLinkData(new_cell.name, new_cell.searchValue);
        // alert("111");

        // 递归处理
        function setLinkData(linkName, linkValue) {
          // 列关联数据处理，支持关联多个父级，但是mapping需要列不同
          $(o.source.data.cellData).each(function (index, cell) {
            if (cell.link) {
              $(cell.link).each(function (linkIndex, linkData) {
                if (linkData.binding == linkName) {
                  // 赋值
                  linkData.value = linkValue;
                  // linkData.name = "哈哈";
                  cell.searchValue = null;
                  // 判断当前控件是否是其他控件的父亲，如果是则同步处理。
                  setLinkData(cell.name, cell.searchValue);
                }
              });
            }
          });
        }

        let IsSearch = false;
        // 在范围模式下只有2个格子都有值，才触发查询。
        if (new_cell.searchKey.toLocaleUpperCase() == "BETWEEN") {
          if (!this.octopus.tools.IsNullOrEmpty(new_cell.searchValue[0]) && !this.octopus.tools.IsNullOrEmpty(new_cell.searchValue[1])) {
            // 进行逻辑判断过滤
            // 日历框/日历时间框（上面已经转义）
            // alert(JSON.stringify(new_cell));
            if (new_cell.controlTypeID == 5) {
              if (new Date(new_cell.searchValue[0]) > new Date(new_cell.searchValue[1])) {
                this.octopus.tips.error("【" + new_cell.displayName + "】开始日期不能大于结束日期。");
              } else {
                new_cell.searchValue[1] = new_cell.searchValue[1] + " 23:59:59";
                IsSearch = true;
              }
            } else {
              IsSearch = true;
            }
          }
          // 如果框都为空了，则也触发查询
          else if (this.octopus.tools.IsNullOrEmpty(new_cell.searchValue[0]) && this.octopus.tools.IsNullOrEmpty(new_cell.searchValue[1])) {
            IsSearch = true;
          }
        } else {
          IsSearch = true;
        }

        if (IsSearch) {
          // 只要涉及到查询的，全部恢复到首页。
          this.source.data.pageData.index = 1;

          // 回调搜索函数给开发使用
          if (this.searched) {
            // 是否托管
            let searchDeposit = this.searched(new_cell, old_cell);
            // 启用托管
            if (searchDeposit != false) {
              this.load();
            }
            // 启用托管
            else {
              console.log("代码已进入托管。");
            }
          }
          // 默认启用load，此时没有申明 searched 接口
          else {
            // // 执行查询
            this.load();
          }

          // 记录搜索日志
          this.octopus.request.api.logger("search", new_cell);
        }
      },
      output: function () {
        let o = this;
        // 支持任意八抓鱼List列表数据导出表格。
        console.log(this.source,'output');
        this.octopus.request.api.export(this.source, function (data) {
          // console.log(JSON.stringify(data));
          // 触发回调
          if (o.exported) {
            o.exported(data);
          }
        });
      },
      del: function (row) {
        // 正常调用自身的删除接口


        if (this.deleted) {
          this.deleted(row);
        }
      },
      reload: function () {
        console.log(JSON.stringify(this.source));
      },
      // 执行加载
      load: function (type) {
        // 满足要求才执行查询
        if (this.source.data.id && this.source.data.cellData) {
          let o = this;
          // 替换层级值（如果有）
          this.source.data.parentValue = this.octopus.tools.parseScript(this.source.data.parentValue);
          // // 循环处理转义相关八抓鱼代码
          // $(this.source.data.cellData).each(function (index, item) {
          //   if (item.filterValue) {
          //     // 只有非范围控件支持绑定关联，所以这里只要判断filterValue下标0的数据即可。
          //     item.filterValue[0] = o.octopus.tools.parseScript(item.filterValue[0]);
          //     // console.log("======" + JSON.stringify(item));
          //   }
          // })
          // })

          // 请求后台八爪鱼API框架，为了节约流量，所以不把queryData大型包再发回去。
          this.octopus.request.api.post("/Octopus/Engine/List", {
              id: this.source.data.id,
              parentKey: this.source.data.parentKey,
              parentValue: this.source.data.parentValue,
              orderData: this.source.data.orderData,
              cellData: this.source.data.cellData,
              pageData: this.source.data.pageData,
              width: this.source.data.width,
              height: this.source.data.height,
              minHeight: this.source.data.minHeight,
              offsetHeight: this.source.data.offsetHeight,
              paramData: this.source.data.paramData,
            },
            // 处理回调事件，通过分析data.status.code的状态来实现。
            function (data) {
              if (data.status.code == 200) {
                // 加载之前，需要注意的是此时数据并不完整，只是刚从后台获取到。
                if (o.loadBefore) {
                  o.loadBefore(data);
                }
                // 打印log
                // console.warn(data.content.height);

                // 计算表格总宽度
                o.source.reallyWidth = 0;
                $(data.content.cellData).each(function (index, cell) {
                  cell.validate = true;
                  cell.model = "LIST";

                  // 处理宽度
                  if (cell.show) {
                    o.source.reallyWidth += cell.width;
                  }

                  ////////////////////// List内控件形态转换逻辑 /////////////////////////
                  // 如果是多行文本框、标签框、富文本框，则修改为文本框，否则查询组件无法查询哈。
                  if (cell.controlTypeID == 2 || cell.controlTypeID == 4 || cell.controlTypeID == 18) {
                    cell.controlTypeID = 1;
                  }
                  // 如果是日历时间框，则改为日历框，否则查询不太友好。
                  else if (cell.controlTypeID == 6) {
                    cell.controlTypeID = 5;
                  }

                });

                // 如果存在配置功能，则需要设置宽度
                if (o.source.configWidth) {
                  o.source.reallyWidth += o.source.configWidth;
                }

                // 如果需要现实序号，则加30宽度
                if (o.source.showNumber) {
                  // 动态识别配置列宽度，此处需要计算出当前分页下的最大值。
                  let NumberMaxIndex = (data.content.pageData.index - 1) * data.content.pageData.rowSize + data.content.pageData.rowSize;
                  // 求出是几位数，然后✖️倍数。
                  let multiple = (NumberMaxIndex + "").length;
                  o.source.numberWidth = 15 + multiple * 6;
                  //
                  o.source.reallyWidth += o.source.numberWidth;
                }

                // 不是父级模式 则 渲染分页
                // if (!data.content.parentModel) {
                if (data.content.pageData) {
                  // 渲染Page对象
                  o.renderPage(data.content.pageData);
                }
                // 二次进入时有数据则只更新cellData, queryData,pageData部分。
                if (o.source.data.queryData) {
                  o.$set(o.source.data, "cellData", data.content.cellData);
                  o.$set(o.source.data, "queryData", data.content.queryData);
                  o.$set(o.source.data, "pageData", data.content.pageData);
                }
                // 首次加载，进行全量更新。
                else {
                  // 新增属性，需要使用$set，详细参考：https://blog.csdn.net/panyang01/article/details/76665448
                  o.$set(o.source, "data", data.content);
                }

                if (o.loaded) {
                  o.loaded(data);
                }
              } else {
                o.octopus.tips.error(data);
              }

              // alert(o.source.data.height);
              // 如果高度为auto或丫根没有定义，则默认理解为自动高度,如果是100%，则认为是List自动识别高度模式
              if (o.source.data.height == "auto") {
                o.resize();
                window.onresize = function () {
                  o.resize();
                }
              }
              // 如果是完整模式，比如多控件组合的，则不限高。
              // else if (o.source.data.height == "full") {
              //   o.control_height = "100%";
              // }
              // 非自动模式，则加载配置的高度，如果需要完成适应（比如以前的full），则可用100%代替。
              else {
                o.control_height = o.source.data.height;
              }

              // 加载行样式，包括高度，样式，宽度等。
              o.parseRowStyle();

              // // 设置行图像样式，因为采用JQuery构件数据，所以延迟1秒。
              // setTimeout(function () {
              //   o.renderRowImage();
              // }, 1000);

              // 初始化link数据
              o.loadLinkData();
            });
        }
      },
      // 设置排序
      sort: function (cell) {
        // console.warn(cell);

        // 设置排序
        let sortValue = cell.name + " DESC";
        // 如果排序相等，则反相
        if (this.source.data.orderData == sortValue) {
          sortValue = cell.name + " ASC";
        }
        this.source.data.orderData = sortValue;
        this.load();
      },
      parseRowStyle: function () {
        /////////////////////////// 初始化行高 ///////////////////////////
        let isImage = false;
        this.source.data.cellData.map((e) => {
          // 如果列显示 并且 有图像上传
          if (e.show && e.controlTypeID == 15) {
            isImage = true;
          }
        });
        // 如果有上传，则全行高100；
        if (isImage) {
          this.row_height = 100;
        }
      },
      // 解析列数据
      parseCellValue: function (row, name) {
        // 得到列数据
        let value = row[name];

        value = value == null ? '&nbsp;' : (value.toString().length > 0 ? value : '&nbsp;');
        if (value == "是") {
          value = "<span class='icon icon70chenggong'>&nbsp;</span>";
        } else if (value == "否") {
          value = "<span class='icon icon71shibai'>&nbsp;</span>";
        } else if (value == "已完成" || value == "已处理") {
          value = "<span class='icon icon70chenggong'>&nbsp;</span>" + value;
        } else if (value == "异常") {
          value = "<span class='icon icon71shibai'>&nbsp;</span>" + value;
        } else if (value == "待处理") {
          value = "<span class='icon icon73dengdai'>&nbsp;</span>" + value;
        } else if (value == "执行中" || value == "处理中") {
          value = "<span class='icon iconxunjian-ing'>&nbsp;</span>" + value;
        } else if (value == "未启动") {
          value = "<span class='icon iconzhihangzhong'>&nbsp;</span>" + value;
        } else if (value == "已关闭") {
          value = "<span class='icon iconhuodong1'>&nbsp;</span>" + value;
        } else if (value == "已退回") {
          value = "<span class='icon icontuihui-'>&nbsp;</span>" + value;
        } else if (value == "已搁置") {
          value = "<span class='icon iconzhushi'>&nbsp;</span>" + value;
        }

        // 如果是parentModel，则对父级字段进行样式绑定，这样就可以由主题进行自由缩进或样式修改。
        if (this.source.data.parentModel) {
          // 检索出所有需要层级显示的列
          let ListFilterData = $.grep(this.source.data.cellData, function (value) {
            return value.hierarchy;//筛选出层级显示为true的列
          });
          // 遍历
          $(ListFilterData).each(function (index, item) {
            if (name == item.name) {
              value = "<span class='level_" + row["ParentLevel"] + "'>" + value + "</span>"
            }
          });
        }

        return value;
      },
      // 计算
      parseRowNumber: function (index) {
        // 求出基本行号
        let rowNumber = index + 1;
        // 计算出翻页部分，如果不是第一页。
        rowNumber = rowNumber + (this.source.data.pageData.index - 1) * this.source.data.pageData.rowSize;

        return rowNumber;
      },
      scroll: function (dom) {
        let SCROLL_VALUE = $(dom).scrollLeft();
        // $(".Data .Head").scrollLeft(SCROLL_VALUE);
        $(this.$refs.LIST_HEAD).scrollLeft(SCROLL_VALUE);
      },
      jump: function (index) {
        // 更新页码
        this.source.data.pageData.index = index;
        // 发起加载
        this.load();
        // 如果有回调事件，把整个page对象回传，交由程序员控制。
        if (this.paged) {
          this.paged(index);
        }
      },
      // 界面的高度撑开由Menu组件实现，故需求写在这里
      resize: function () {
        let o = this;
        $(document).ready(function () {
          // 延迟0.5秒加载高度
          setHeight();

          // 启动高度设定
          function setHeight() {
            // 设置控件高度
            let controlHeight = 0;
            //o.control_height = 0;
            setTimeout(function () {
              // 下列算法当有研发在list控件外层包了浮动以后，会导致异常，因为浮动以后，文档高度（ $(document.body).height()）就为0了。
              // let list_height = $(window).height() - $(document.body).height();
              // 列表高度 = 可视区高度 - 文档高度（上面高度已经设置位0，所以文档高度正常情况都是小于可视区高度的）
              let list_height = $(window).height() - ($(".Operation").height() ? $(".Operation").height() : 0)
                - ($(".Search").height() ? $(".Search").height() : -11) - 85; //
              // 此处可能是由于查询框样式的原因导致如果没有查询框时，要自动扣除11像素

              // 列表高度 大于 0 才有设置的意义，否则太小，出滚动条。
              if (list_height > 0) {

                controlHeight = list_height;
                // 偏移量情况下的高度自适应。
                if (o.source.data.offsetHeight) {
                  controlHeight = controlHeight - o.source.data.offsetHeight;
                }
                // 最小高度限定。
                if (o.source.data.minHeight) {
                  controlHeight = controlHeight < o.source.data.minHeight ? o.source.data.minHeight : controlHeight;
                }

                o.control_height = controlHeight + "px";
              }
              // alert(o.source.data.height + "|" + o.source.data.minHeight + "|" + o.source.data.offsetHeight);
              // console.log("设置高度：" + o.control_height + "，窗体高度：" + $(window).height() + "，测试高度：" + controlHeight);
              // console.log("doc hei:" + $(document).outerHeight() + ", 可视区高度：" + $(window).height()
              //   + ", 文档高度：" + $(document.body).height() + ", " + "分页高度：" + $(".Page").outerHeight());
            }, 500);
          }
        });
      },
      open: function () {
        window.open(window.location.href, '_blank')
        // alert(window.location.href);
      },
      renderPage: function (pageData) {
        // 渲染list数据
        $(pageData.listData).each(function (index, page) {
          if (page.type == "Home") {
            page.index
            page.class = "icon iconjurassic_home-page";
          } else if (page.type == "Previous") {
            page.class = "icon iconjurassic_previous-page";
          } else if (page.type == "Next") {
            page.class = "icon iconjurassic_next-page";
          } else if (page.type == "End") {
            page.class = "icon iconjurassic_end-page";
          } else {
            page.text = page.index;
          }
        });
      },
      // 渲染行图像事件。
      renderImageView: function (path) {
        //
        this.imageViewPanel = true; // 图像面板显示
        this.imageViewPath = path;
      },
      ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
      ltDetailFun() {
        console.log(this.octopus.passport);
        console.log("执行了子组件中的方法。");
      },
      pushFatherFun() {
        this.$emit("subsendfather", "44556677");
      },
      remove: function () {
        // 采用样式删除，会导致所有使用这个样式的DOM被删除。
        // $(".jubuCp").remove();
        this.octopus.tips.debug("Item.vue.vue执行了 remove 事件。");
      },
      event: function (callback) {
        callback(this.source.data);
      }
    },
    watch: {
      // 监听计算属性的变化
      changeCell: function (newval, oldval) {
        console.log("changeCell:\nOLD: " + JSON.stringify(oldval) + "\n\nNEW: " + JSON.stringify(newval));
      }
      // source: {
      //   handler(newval, oldval) {
      //     console.log("waa: " + JSON.stringify(oldval.data.cellData) + "变更为" + JSON.stringify(newval.data.cellData));
      //   },
      //   deep: true // 启用深度监听模式，可监控到属性。
      // }
    },
    props: ["source", "loadBefore", "loaded", "created", "backed", "exported", "searched", "paged", "viewed", "modified", "deleted"]
  }
</script>

/*  scoped的意思是这里的样式只对当前页面有效不会影响其他页面，还有可以设置lang="scss"就是支持css预编译，也就是支持sass或者less  */
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  h1, h2 {
    font-weight: normal;
  }
</style>
